package com.irdstudio.efp.esb.api.service.yed;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.irdstudio.basic.framework.core.constant.BaseConstant;
import com.irdstudio.basic.framework.core.constant.DateFormatConstant;
import com.irdstudio.basic.framework.core.constant.EsbRetCodeStandard;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.exception.ESBException;
import com.irdstudio.basic.framework.core.threadpool.ApplicationThreadPool2;
import com.irdstudio.basic.framework.core.util.DateUtility;
import com.irdstudio.basic.framework.core.util.RandomCodeUtils;
import com.irdstudio.basic.framework.core.util.TimeUtil;
import com.irdstudio.efp.basic.framework.mq.client.producer.MQProducerMessageClient;
import com.irdstudio.efp.basic.framework.mq.constant.TagEnums;
import com.irdstudio.efp.basic.framework.mq.constant.TopicEnums;
import com.irdstudio.efp.cus.service.vo.KafkaNoticeHeader;
import com.irdstudio.efp.esb.api.rest.yed.req.YedCreditRiskApproveNoticeReqBean;
import com.irdstudio.efp.esb.common.constant.MsLoanConstant;
import com.irdstudio.efp.esb.common.constant.dxm.DxmEnum;
import com.irdstudio.efp.esb.common.server.resp.EsbRespServiceBean;
import com.irdstudio.efp.esb.service.bo.req.sx.CreditBasicInfo;
import com.irdstudio.efp.esb.service.bo.req.sx.CreditExpanding;
import com.irdstudio.efp.esb.service.bo.req.sx.CreditMessage;
import com.irdstudio.efp.esb.service.bo.req.sx.CreditReq;
import com.irdstudio.efp.esb.service.facade.sx.CreditService;
import com.irdstudio.efp.nls.common.constant.NlsProcessBizEnums;
import com.irdstudio.efp.nls.common.constant.PrdAdaptedSoltEnums;
import com.irdstudio.efp.nls.common.constant.QueueTaskEnums;
import com.irdstudio.efp.nls.common.util.KafkaUtil;
import com.irdstudio.efp.nls.common.util.NlsStringUtil;
import com.irdstudio.efp.nls.service.facade.NlsStageInfoService;
import com.irdstudio.efp.nls.service.facade.psd.NlsCreditApprovalInfoService;
import com.irdstudio.efp.nls.service.facade.queue.NlsProcessBizService;
import com.irdstudio.efp.nls.service.facade.queue.NlsProcessRuleService;
import com.irdstudio.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.irdstudio.efp.nls.service.vo.NlsCreditInfoNoticeVO;
import com.irdstudio.efp.nls.service.vo.NlsStageInfoVO;
import com.irdstudio.efp.nls.service.vo.psd.NlsCreditApprovalInfoVO;
import com.irdstudio.efp.nls.service.vo.queue.NlsProcessBizVO;
import com.irdstudio.efp.nls.service.vo.queue.NlsProcessRuleVO;
import com.irdstudio.efp.nls.service.vo.sx.NlsCreditInfoVO;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.rocketmq.common.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Locale;

/**
 * 需求编号：优e贷风控审批通知业务处理<br/>
 * 问题编号：<br/>
 * 功能描述：<br/>
 * 开发人员：dengqiwen<br/>
 * 创建时间：2020/7/30 14:56
 */
@Service("nlsYedCreditNoticeProcess")
public class NlsYedCreditNoticeProcess {

    /**
     * 日志
     */
    private Logger logger = LoggerFactory.getLogger(NlsYedCreditNoticeProcess.class);

    // 日志ID
    private static final String LOGGER_ID = "优e贷-授信风控结果通知";

    /**
     * 授信申请服务
     */
    @Autowired
    @Qualifier("nlsCreditInfoService")
    private NlsCreditInfoService nlsCreditInfoService;

    @Autowired
    @Qualifier("creditService")
    private CreditService creditService;

    @Autowired
    @Qualifier("producerService")
    private MQProducerMessageClient producerService;


    @Autowired
    @Qualifier("nlsProcessRuleService")
    private NlsProcessRuleService nlsProcessRuleService;

    @Autowired
    @Qualifier("nlsProcessBizService")
    private NlsProcessBizService nlsProcessBizService;

    @Autowired
    @Qualifier("nlsCreditApprovalInfoService")
    private NlsCreditApprovalInfoService nlsCreditApprovalInfoService;

    @Autowired
    @Qualifier("applicationThreadPool")
    private ApplicationThreadPool2 threadPool;

    @Autowired
    @Qualifier("nlsStageInfoService")
    private NlsStageInfoService nlsStageInfoService;



    // kafka发送的主题topic
    @Value("${risk.kafkaToptic}")
    private String kafkaToptic;

    // kafka主机IP地址
    @Value("${risk.kafkaServers}")
    private String kafkaServers;

    public void processCreditResult(YedCreditRiskApproveNoticeReqBean yedCreditRiskApproveNoticeReqBean) throws BizException {

       try {
        NlsCreditInfoVO selectCreditInfo = nlsCreditInfoService.queryByLmtApplySeq(yedCreditRiskApproveNoticeReqBean.getCrAppSrlNo());
        // 授信申请信息校验
        if (selectCreditInfo == null) {
            logger.error("优e贷授信通知 授信申请流水号:【"+yedCreditRiskApproveNoticeReqBean.getCrAppSrlNo()+"】 查询不到授信申请信息!");
            throw new ESBException(EsbRetCodeStandard.YWLJCLYC.getValue(), yedCreditRiskApproveNoticeReqBean.getCrAppSrlNo() + " 查询不到授信申请信息!");
        }

        /** 最近修改时间 **/
        selectCreditInfo.setLastUpdateTime(DateUtility.getCurrAppDateTimeString());
        /** 审批时间 **/
        selectCreditInfo.setApprvDate(DateUtility.getCurrDate());
        //工作单位名称
         selectCreditInfo.setWrkCorpNm(yedCreditRiskApproveNoticeReqBean.getWrkCorpNm());

        //失败 ，包含风控返回异常
        if (!isApproveAccess(yedCreditRiskApproveNoticeReqBean)) {

            /** 设置审批状态信息为拒绝 **/
            selectCreditInfo.setApprvSts(MsLoanConstant.NlsApplyStateEnum.REJECT.getVALUE());

            if (isApproveFailure(yedCreditRiskApproveNoticeReqBean)) {
                selectCreditInfo.setRefuseCause(NlsStringUtil.toShorterString(yedCreditRiskApproveNoticeReqBean.getRfsCd()+"|"+yedCreditRiskApproveNoticeReqBean.getRfsRsn(),500));
            } else if (isApproveException(yedCreditRiskApproveNoticeReqBean)) {
                selectCreditInfo.setRefuseCause(NlsStringUtil.toShorterString("风控系统授信审批异常:"+yedCreditRiskApproveNoticeReqBean.getRfsCd()+"|"+yedCreditRiskApproveNoticeReqBean.getRfsRsn(),500));
            }
            selectCreditInfo.setApprvSts(MsLoanConstant.NlsApplyStateEnum.REJECT.getVALUE());
            //插入授信审批信息表
            insertCreditApproveInfo(yedCreditRiskApproveNoticeReqBean,selectCreditInfo);
            //更新授信申请表
            updateCreditInfo( selectCreditInfo);

        }else{
            //风控返回成功
            //插槽阶段，授信阶段
            selectCreditInfo.setSoltStage(PrdAdaptedSoltEnums.SoltStageEnum.CREDIT.getVALUE());
            selectCreditInfo.setApproveAmt(new BigDecimal(yedCreditRiskApproveNoticeReqBean.getCrRcmndnAmt()));//审批金额
            selectCreditInfo.setApplyAmt(new BigDecimal(yedCreditRiskApproveNoticeReqBean.getCrRcmndnAmt()));//申请金额
            selectCreditInfo.setApproveRateY(new BigDecimal(yedCreditRiskApproveNoticeReqBean.getAnulIntRt()));//批复执行年利率
            //更新授信申请表
            updateCreditInfo( selectCreditInfo);
            //插入授信审批信息表
            insertCreditApproveInfo(yedCreditRiskApproveNoticeReqBean,selectCreditInfo);
            //发送mq
            sendMessageIfApproveAccess(selectCreditInfo);
        }
            //发送kafka消息给风控
           sendToRisk(selectCreditInfo);
    } catch (BizException e) {
        logger.error(LOGGER_ID,"优e贷授信申请异常,流水号："+yedCreditRiskApproveNoticeReqBean.getCrAppSrlNo()+e.getMessage());
        throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), "优e贷风控审批通知接口出现异常："+ NlsStringUtil.toShorterString(e.getMessage(),50));
    } catch (UnsupportedEncodingException e) {
        logger.error(LOGGER_ID,"优e贷授信申请发送消息到mq出现异常,流水号："+yedCreditRiskApproveNoticeReqBean.getCrAppSrlNo()+e.getMessage());
        e.printStackTrace();
        throw new BizException(EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "优e贷风控审批接口发送消息到mq出现异常："+ NlsStringUtil.toShorterString(e.getMessage(),50));
    } catch (Exception e) {
        logger.error(LOGGER_ID,"优e贷授信申请出现异常,流水号："+yedCreditRiskApproveNoticeReqBean.getCrAppSrlNo()+e.getMessage());
        e.printStackTrace();
        throw new BizException(EsbRetCodeStandard.OTHERS_EXCEPTION.getValue(), "优e贷风控审批通知接口出现异常："+ NlsStringUtil.toShorterString(e.getMessage(),50));
    }

    }


    private void insertCreditApproveInfo(YedCreditRiskApproveNoticeReqBean yedCreditRiskApproveNoticeReqBean, NlsCreditInfoVO selectCreditInfo) throws BizException {
        NlsCreditApprovalInfoVO nlsCreditInfoApprovalVO =new NlsCreditApprovalInfoVO();
        nlsCreditInfoApprovalVO.setLmtApplySeq(selectCreditInfo.getLmtApplySeq());//授信申请流水号
        nlsCreditInfoApprovalVO.setGlobalSerno(selectCreditInfo.getGlobalSerno());//全局流水号
        nlsCreditInfoApprovalVO.setApprResult(yedCreditRiskApproveNoticeReqBean.getAprvlRsltFlg());//审批结果
        nlsCreditInfoApprovalVO.setApproveTime(new Date());//审批时间
        nlsCreditInfoApprovalVO.setMannualApproveFlag(yedCreditRiskApproveNoticeReqBean.getMnulAprvlFlg());//人工审批标志
        nlsCreditInfoApprovalVO.setApplyRateY(new BigDecimal(yedCreditRiskApproveNoticeReqBean.getAnulIntRt()));//年利率
        nlsCreditInfoApprovalVO.setApproveAmt(new BigDecimal(yedCreditRiskApproveNoticeReqBean.getCrRcmndnAmt()));//风控建议金额
        nlsCreditInfoApprovalVO.setApproveTerm(yedCreditRiskApproveNoticeReqBean.getLoanAplTrm());//风控建议期限
        nlsCreditInfoApprovalVO.setApproveTermType(yedCreditRiskApproveNoticeReqBean.getLoanTrmType());//风控建议期限类型
        nlsCreditInfoApprovalVO.setCreateTime(new Date());
        nlsCreditInfoApprovalVO.setCreateUser(BaseConstant.ADMIN);
        nlsCreditInfoApprovalVO.setLastUpdateUser(BaseConstant.ADMIN);
        nlsCreditInfoApprovalVO.setLastUpdateTime(new Date());
        if (!isApproveAccess(yedCreditRiskApproveNoticeReqBean)) {
            nlsCreditInfoApprovalVO.setRefuseCode(yedCreditRiskApproveNoticeReqBean.getRfsCd());
            nlsCreditInfoApprovalVO.setRefuseMsg(yedCreditRiskApproveNoticeReqBean.getRfsRsn());
        }
        int result = nlsCreditApprovalInfoService.insert(nlsCreditInfoApprovalVO);
        if (result != 1) {
            throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), "优e贷更新授信审批信息失败");
        }
    }

    private void updateCreditInfo(NlsCreditInfoVO nlsCreditInfoVO) throws BizException {
        int result = nlsCreditInfoService.updateByPk(nlsCreditInfoVO);
        if (result != 1) {
            throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), "优e贷更新授信信息失败");
        }
    }


    private void sendMessageIfApproveAccess(NlsCreditInfoVO nlsCreditInfoVO) throws UnsupportedEncodingException {
        nlsCreditInfoVO.setSoltStage(PrdAdaptedSoltEnums.YedSoltStageEnum.CREDIT.getVALUE());
        //因为之前发过一次这个流水号的mq，所以这次key要加一个后缀，才能不重复，不影响功能
        producerService.sendMsg(new Message(TopicEnums.QUEUE_TASK_CREDIT_TOPIC.getTopicId(), TagEnums.TAG_QUEUE_CREDIT_TASK.getTagId(),
                nlsCreditInfoVO.getLmtApplySeq()+"-1",
                JSON.toJSONString(nlsCreditInfoVO).getBytes("UTF-8")));
    }

    private boolean isApproveAccess(YedCreditRiskApproveNoticeReqBean yedCreditRiskApproveNoticeReqBean) {
        return "Y".equals(yedCreditRiskApproveNoticeReqBean.getAprvlRsltFlg().trim()) ? true : false;
    }
    private boolean isApproveException(YedCreditRiskApproveNoticeReqBean yedCreditRiskApproveNoticeReqBean) {
        return "E".equals(yedCreditRiskApproveNoticeReqBean.getAprvlRsltFlg().trim()) ? true : false;
    }
    private boolean isApproveFailure(YedCreditRiskApproveNoticeReqBean yedCreditRiskApproveNoticeReqBean) {
        return "N".equals(yedCreditRiskApproveNoticeReqBean.getAprvlRsltFlg().trim()) ? true : false;
    }


    private void sendToRisk(NlsCreditInfoVO nlsCreditInfoVO) {
        // 授信申请流水号
        String applySeq = nlsCreditInfoVO.getLmtApplySeq();
        logger.info("优e贷授信，发送kafka消息给大数据开始执行,流水号:" + applySeq);
        try {
            boolean flag = false;
            //查询开关
            List<NlsStageInfoVO> infoVOS = nlsStageInfoService.queryList();
            for(NlsStageInfoVO vo:infoVOS){
                if(vo.getPrdId().equals("11110004") && vo.getStatus().equals("on") && vo.getStage().equals("credit")){
                    flag = true;
                }
            }
            JSONObject jsonObject = new JSONObject();
            NlsCreditInfoNoticeVO array = new NlsCreditInfoNoticeVO();
            array.setTableName("NLS_CREDIT_INFO");
            //数据日期
            String timeStamp = TimeUtil.getTimeStampByPattern("yyyy-MM-dd HH:mm:ss");
            array.setApproveAmt(nlsCreditInfoVO.getApproveAmt());
            array.setApprvSts(nlsCreditInfoVO.getApprvSts());
            array.setLmtApplySeq(nlsCreditInfoVO.getLmtApplySeq());
            array.setRefuseCause(nlsCreditInfoVO.getRefuseCause());
            array.setDataTime(timeStamp);

            KafkaNoticeHeader header = new KafkaNoticeHeader();
            header.setMessageCode("YED_JISHI");
            header.setTimestamp(timeStamp);
            header.setTransactionId(getTransactionId());
            header.setSysName("netLoan");

            jsonObject.put("head", header);
            jsonObject.put("biz", array);

            if(!flag){
                logger.info("实时采集开关未打开！！！");
                return;
            }
            threadPool.add(() -> {
                KafkaUtil kafkaUtil = new KafkaUtil(kafkaServers, kafkaToptic);
                try {
                    kafkaUtil.sendMessage(JSONObject.toJSONString(jsonObject));
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("优e贷授信，发送kafka消息给大数据失败，流水号：" + applySeq + ",异常信息：" + e.getMessage());
                }
            });
        } catch (Exception e) {
            logger.info("优e贷授信，发送kafka消息给大数据异常，流水号：" + applySeq + ",异常信息：" + e.getMessage());
        } finally {
            logger.info("优e贷授信，发送kafka消息给大数据结束，申请流水号：" + applySeq);
        }
    }

    public static String getTransactionId() {
        String transactionId = "SEQ" + DateFormatUtils.format(new Date(), DateFormatConstant.DATETIME_FORMAT_COMPACT, Locale.CHINA) +
                RandomCodeUtils.generateLetter(6);
        return transactionId;
    }

}
